package com.hushan.elevator.service.impl;

import com.hushan.elevator.dao.DepartmentRepository;
import com.hushan.elevator.dao.DeviceInfoRepository;
import com.hushan.elevator.dao.DeviceLogRepository;
import com.hushan.elevator.dto.RiskRecordDto;
import com.hushan.elevator.enums.DeviceBusinessType;
import com.hushan.elevator.model.Department;
import com.hushan.elevator.model.DeviceInfo;
import com.hushan.elevator.model.DeviceLog;
import com.hushan.elevator.model.User;
import com.hushan.elevator.security.SecurityUtils;
import com.hushan.elevator.service.DeviceLogService;
import com.hushan.elevator.vo.LogInfoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class DeviceLogServiceImpl implements DeviceLogService {

    private final DeviceLogRepository deviceLogDao;
    private final DeviceInfoRepository deviceInfoDao;
    private final DepartmentRepository deptDao;
    @Autowired
    public DeviceLogServiceImpl(DeviceLogRepository deviceLogDao, DeviceInfoRepository deviceInfoDao, DepartmentRepository deptDao) {
        this.deviceLogDao = deviceLogDao;
        this.deviceInfoDao = deviceInfoDao;
        this.deptDao = deptDao;
    }

    @Override
    public Page<LogInfoVo> findAllDeviceLogs(Pageable pageable) {
        User user = SecurityUtils.getUser();
        Department dept = deptDao.findUserDept(user.getUserId());
        Page<Object[]> deviceLogs = deviceLogDao.findDeviceLog(dept.getDeptId(), null, pageable);
        List<LogInfoVo> logInfoVos = convertRiskRecordDto(deviceLogs.stream().toList());

        Page<LogInfoVo> rst = new PageImpl<>(logInfoVos, pageable, deviceLogs.getTotalElements());
        return rst;
    }

    @Override
    public Page<LogInfoVo> findDeviceLogsByDeviceId(String deviceSerial, Pageable pageable) {
        User user = SecurityUtils.getUser();
        Department dept = deptDao.findUserDept(user.getUserId());
        Page<Object[]> deviceLogs = deviceLogDao.findDeviceLog(dept.getDeptId(), deviceSerial, pageable);
        List<LogInfoVo> logInfoVos = convertRiskRecordDto(deviceLogs.stream().toList());

        Page<LogInfoVo> rst = new PageImpl<>(logInfoVos, pageable, deviceLogs.getTotalElements());
        return rst;
    }

    @Override
    public DeviceLog findDeviceLogById(Integer id) {
        return deviceLogDao.findById(id).orElse(null);
    }

    @Override
    public void online(DeviceInfo deviceInfo, int isOnline) {
        DeviceLog deviceLog = new DeviceLog();
        deviceLog.setDeviceSerial(deviceInfo.getSerialNumber());
        deviceLog.setBusinessType(DeviceBusinessType.ONLINE.ordinal());
        deviceLog.setLogMessage(DeviceBusinessType.ONLINE.getDescription());
        deviceLogDao.save(deviceLog);
    }

    @Override
    public void onMessage(DeviceInfo deviceInfo, String string) {
        DeviceLog deviceLog = new DeviceLog();
        deviceLog.setDeviceSerial(deviceInfo.getSerialNumber());
        deviceLog.setBusinessType(DeviceBusinessType.MSG.ordinal());
        deviceLog.setLogMessage(DeviceBusinessType.MSG.getDescription()+": "+string);
        deviceLog.setDetail(string);
        deviceLogDao.save(deviceLog);

    }

    @Override
    public void onWarning(String devid, String eventId, String warningType,String detail) {
        DeviceLog deviceLog = new DeviceLog();
        deviceLog.setDeviceSerial(devid);
        deviceLog.setBusinessType(DeviceBusinessType.WARNING.ordinal());
        deviceLog.setEventId(eventId);
        deviceLog.setLogMessage(DeviceBusinessType.WARNING.getDescription()+": "+warningType);
        deviceLog.setDetail(detail);
        deviceLogDao.save(deviceLog);
    }

    @Override
    public void onCapture(String devid, String eventId) {
        DeviceLog deviceLog = new DeviceLog();
        deviceLog.setDeviceSerial(devid);
        deviceLog.setBusinessType(DeviceBusinessType.CAPTURE.ordinal());
        deviceLog.setEventId(eventId);
        deviceLog.setLogMessage(DeviceBusinessType.CAPTURE.getDescription());
        deviceLogDao.save(deviceLog);
    }

    @Override
    public void onConnect(DeviceInfo deviceInfo) {
        DeviceLog deviceLog = new DeviceLog();
        deviceLog.setDeviceSerial(deviceInfo.getSerialNumber());
        deviceLog.setBusinessType(DeviceBusinessType.CONNECTED.ordinal());
        deviceLog.setLogMessage(DeviceBusinessType.CONNECTED.getDescription());
        deviceLogDao.save(deviceLog);
    }

    @Override
    public void onDisConnect(DeviceInfo deviceInfo) {
        DeviceLog deviceLog = new DeviceLog();
        deviceLog.setDeviceSerial(deviceInfo.getSerialNumber());
        deviceLog.setBusinessType(DeviceBusinessType.DISCONNECTED.ordinal());
        deviceLog.setLogMessage(DeviceBusinessType.DISCONNECTED.getDescription());
        deviceLogDao.save(deviceLog);
    }

    @Override
    public void onError(String devid, String logMessage, String detail) {
        DeviceLog deviceLog = new DeviceLog();
        deviceLog.setDeviceSerial(devid);
        deviceLog.setBusinessType(DeviceBusinessType.ERROR.ordinal());
        deviceLog.setLogMessage(DeviceBusinessType.ERROR.getDescription()+":"+logMessage);
        deviceLog.setDetail(detail);
        deviceLogDao.save(deviceLog);
    }

    @Override
    public List<LogInfoVo> convertRiskRecordDto(List<Object[]> raws) {
        return raws.stream()
                .map(LogInfoVo::new)
                .collect(Collectors.toList());
    }

}